/**
 * 
 */
package ru.opedge.notifical.notification.service.google;

import java.net.URL;

import ru.opedge.notifical.notification.Notification;
import ru.opedge.notifical.notification.service.AuthException;
import ru.opedge.notifical.notification.service.INotificationService;
import ru.opedge.notifical.notification.service.ServiceException;

import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.Link;
import com.google.gdata.data.batch.BatchStatus;
import com.google.gdata.data.batch.BatchUtils;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.util.AuthenticationException;

/**
 * @author opedge
 * 
 */
public abstract class GCalService implements INotificationService
{
	public final static String URL_PREFIX = "http://www.google.com/calendar/feeds/";

	public final static String URL_POSTFIX = "/private/full";

	private String username;

	private final CalendarService calendarService;

	public GCalService(final String appName)
	{
		calendarService = new CalendarService(appName);
	}

	public void setUserCredentials(final String username, final String password)
			throws AuthException
	{
		this.username = username;

		try
		{
			calendarService.setUserCredentials(username, password);
		}
		catch (final AuthenticationException e)
		{
			throw new AuthException("Google Service: invalid login or password");
		}
	}

	public abstract CalendarEventFeed getRequest(Notification notification);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * ru.opedge.notifical.service.INotificationService#saveNotification(ru.
	 * opedge.notifical.notification.INotification)
	 */
	@Override
	public void saveNotification(final Notification notification)
			throws ServiceException
	{
		CalendarEventFeed feed = null;
		try
		{
			final URL defaultEventFeedUrl = new URL(URL_PREFIX + username
					+ URL_POSTFIX);

			feed = calendarService.getFeed(defaultEventFeedUrl,
					CalendarEventFeed.class);
		}
		catch (final Exception e)
		{
			throw new ServiceException("Couldn't get calendar feed.");
		}

		final CalendarEventFeed request = getRequest(notification);
		final Link batchLink = feed
				.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);

		CalendarEventFeed response = null;
		try
		{
			response = calendarService.batch(new URL(batchLink.getHref()),
					request);

			// Ensure that all the operations were successful.
			for (final CalendarEventEntry entry : response.getEntries())
			{
				final String batchId = BatchUtils.getBatchId(entry);
				if (!BatchUtils.isSuccess(entry))
				{
					final BatchStatus status = BatchUtils.getBatchStatus(entry);
					throw new Exception(batchId + " failed ("
							+ status.getReason());
				}
			}
		}
		catch (final Exception e)
		{
			throw new ServiceException("Couldn't save notification "
					+ e.getMessage());
		}
	}

}
